#include "hplcqinfineprotocolcommon.h"
#include <QDebug>
#include "common/convert.h"

#include "common/hplcqinfinepfcid.h"
#include "common/hplcqinfinepacketformat.h"
#include "common/hplcqinfinefindpacket.h"
#include "common/hplcqinfineprotocolcommondata.h"
#include "common/hplcqinfineparsecommonpacket.h"
#include "common/hplcqinfineparsecommonsystempacket.h"
#include "common/hplcqinfinemakepacket.h"
#include "common/hplcqinfinesendcommonpacket.h"
#include "common/hplcqinfinesendcommonsystempacket.h"

#include "modulehplccmdid.h"
#include <QVariant>

namespace hplc
{
namespace qinfine
{

HplcQinfineProtocolCommon::HplcQinfineProtocolCommon(CommonParam &param, QObject *parent)
    : HplcQinfineProtocolCommon(*new HplcQinfineProtocolCommonData(), param, parent)
{

}

HplcQinfineProtocolCommon::HplcQinfineProtocolCommon(HplcQinfineProtocolCommonData &data, CommonParam &param, QObject *parent)
    : BaseProtocol (data, parent)
{
    HplcQinfineMakePacket *maker = new HplcQinfineMakePacket(data);
    HplcQinfineCheckPacket *checker = new HplcQinfineCheckPacket(data, this);

    HplcQinfineParseCommonSystemPacket *commonSystemParser = new HplcQinfineParseCommonSystemPacket(data, param, this);
    HplcQinfineSendCommonSystemPacket *commonSystemSender = new HplcQinfineSendCommonSystemPacket(data);

    data.m_maker = maker;
    data.m_checker = checker;
    data.m_commonSystemParser = commonSystemParser;
    data.m_commonSystemSender = commonSystemSender;

    connect(commonSystemParser, &HplcQinfineParseCommonSystemPacket::setModel, this, &HplcQinfineProtocolCommon::setModel);
    connect(commonSystemParser, &HplcQinfineParseCommonSystemPacket::parseCompleted, this, &HplcQinfineProtocolCommon::parseCompleted);
}

HplcQinfineProtocolCommon::~HplcQinfineProtocolCommon()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    delete m_d->m_maker;
    delete m_d->m_checker;
    delete m_d->m_commonSystemParser;
    delete m_d->m_commonSystemSender;
}

bool HplcQinfineProtocolCommon::setConfig(int id, const QVariant &var)
{
    switch (id)
    {
        case 0:
        {
            quint8 address = var.toUInt();
            HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
            m_d->m_address = address;
        }
        break;
        default:
        return false;
        break;
    }
    return true;
}

bool HplcQinfineProtocolCommon::getConfig(int id, QVariant &var)
{
    switch (id)
    {
        case 0:
        {
            HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
            var.setValue(m_d->m_address);
        }
        break;
        default:
        return false;
        break;
    }
    return true;
}

bool HplcQinfineProtocolCommon::setProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // common
        case hplc::CommonCmdID_SetDeviceAddress:
            getCommonSender()->setDeviceAddress(var.toUInt());
        break;
        case hplc::CommonCmdID_SetSyncTime:
            getCommonSender()->setSyncTime(var.toUInt());
        break;
        case hplc::CommonCmdID_SetOutput:
            {
            hplc::Output output = var.value<hplc::Output>();
            getCommonSender()->setOutput(output.number, output.level);
            }
        break;
        case hplc::CommonCmdID_SetTick:
            getCommonSender()->setTick();
        break;

        // common system
        case hplc::CommonSystemCmdID_SetReset:
            getCommonSystemSender()->setReset();
        break;
        case hplc::CommonSystemCmdID_SetRestoreDefault:
            getCommonSystemSender()->setRestoreDefault(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetSaveAsDefault:
            getCommonSystemSender()->setSaveAsDefault();
        break;
        case hplc::CommonSystemCmdID_SetSuperPassword:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setSuperPassword(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetProductDate:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setProductDate(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetSerialNumber:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setSerialNumber(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetModel:
            getCommonSystemSender()->setModel(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetModelString:
            {
            QString tmp = var.toString();
            char *p = tmp.toUtf8().data();
            getCommonSystemSender()->setModelString(p);
            }
        break;
        case hplc::CommonSystemCmdID_SetUsedTime:
            getCommonSystemSender()->setUsedTime(var.toUInt());
        break;
        case hplc::CommonSystemCmdID_SetProtocol:
            getCommonSystemSender()->setProtocol(var.toUInt());
        break;
        default:
            return false;
        break;
    }
    return true;
}

bool HplcQinfineProtocolCommon::getProtocolCmd(int id, QVariant &var)
{
    switch (id)
    {
        // common
        case hplc::CommonCmdID_GetDeviceAddress:
            getCommonSender()->getDeviceAddress();
        break;
        case hplc::CommonCmdID_GetSoftwareVersion:
            getCommonSender()->getSoftwareVersion();
        break;
        case hplc::CommonCmdID_GetHardwareVersion:
            getCommonSender()->getHardwareVersion();
        break;
        case hplc::CommonCmdID_GetProductDate:
            getCommonSender()->getProductDate();
        break;
        case hplc::CommonCmdID_GetSerialNumber:
            getCommonSender()->getSerialNumber();
        break;
        case hplc::CommonCmdID_GetModel:
            getCommonSender()->getModel();
        break;
        case hplc::CommonCmdID_GetUsedTime:
            getCommonSender()->getUsedTime();
        break;
        case hplc::CommonCmdID_GetSyncTime:
            getCommonSender()->getSyncTime();
        break;
        case hplc::CommonCmdID_GetInput:
            getCommonSender()->getInput(var.toUInt());
        break;
        case hplc::CommonCmdID_GetOutput:
            getCommonSender()->getOutput(var.toUInt());
        break;
        case hplc::CommonCmdID_GetSystemError:
            getCommonSender()->getSystemError();
        break;

        // common system
        case hplc::CommonSystemCmdID_GetSuperPassword:
            getCommonSystemSender()->getSuperPassword();
        break;
        case hplc::CommonSystemCmdID_GetSoftwareVersion:
            getCommonSystemSender()->getSoftwareVersion();
        break;
        case hplc::CommonSystemCmdID_GetHardwareVersion:
            getCommonSystemSender()->getHardwareVersion();
        break;
        case hplc::CommonSystemCmdID_GetProductDate:
            getCommonSystemSender()->getProductDate();
        break;
        case hplc::CommonSystemCmdID_GetSerialNumber:
            getCommonSystemSender()->getSerialNumber();
        break;
        case hplc::CommonSystemCmdID_GetModel:
            getCommonSystemSender()->getModel();
        break;
        case hplc::CommonSystemCmdID_GetModelString:
            getCommonSystemSender()->getModelString();
        break;
        case hplc::CommonSystemCmdID_GetUsedTime:
            getCommonSystemSender()->getUsedTime();
        break;
        case hplc::CommonSystemCmdID_GetAllData:
            getCommonSystemSender()->getAllData();
        break;
        case hplc::CommonSystemCmdID_GetProtocol:
            getCommonSystemSender()->getProtocol();
        break;
        default:
            return false;
        break;
    }
    return true;
}

HplcQinfineCheckPacket *HplcQinfineProtocolCommon::getChecker()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    return m_d->m_checker;
}

HplcQinfineParseCommonPacket *HplcQinfineProtocolCommon::getCommonParser()
{
    return static_cast<HplcQinfineParseCommonPacket*>(m_d->m_parser);
}

HplcQinfineSendCommonSystemPacket *HplcQinfineProtocolCommon::getCommonSystemSender()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemSender;
}

void HplcQinfineProtocolCommon::setModel(quint8 model)
{
    Q_UNUSED(model)
}

HplcQinfineParseCommonSystemPacket *HplcQinfineProtocolCommon::getCommonSystemParser()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    return m_d->m_commonSystemParser;
}

HplcQinfineSendCommonPacket *HplcQinfineProtocolCommon::getCommonSender()
{
    return static_cast<HplcQinfineSendCommonPacket*>(m_d->m_sender);
}

void HplcQinfineProtocolCommon::onBaseTickTimeout()
{
    HplcQinfineProtocolCommonData *m_d = static_cast<HplcQinfineProtocolCommonData*>(this->m_d);
    m_d->m_checker->onBaseTickTimeout();
}

} // qinfine
} // hplc
